﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Core.PageEntities;
using Core.PageInterfaces;
using Infrastructure;
using Infrastructure.Managers;
using Newtonsoft.Json;
using RhotCMS.Models;
using Core.Logging;
using WebMatrix.WebData;
using System.Web.Security;
using Core.Users;
using RhotCMS.Filters;
using Core.Constants;
using Core.SupportEntities;
using Utils;
using Core.Store;
using Infrastructure.ExtendedEntities;

namespace RhotCMS.Controllers
{
    public class AdministrationController : RhotCMSController
    {
        public AdministrationController(ILogger logger, ICurrentUserService user)
            : base(logger, user)
        {
            _pageManager = new PageManager();
            _cacheManager = new CacheManager();
            _userManager = new MembershipRepository();
            _storeManager = new StoreManager();
            _systemSettingsManager = new SystemSettingsManager();

            var currentUserName = _currentUserService.CurrentUser.Identity.Name;
            if (!_userManager.IsUserInRole(currentUserName, ConstantsSettings.STR_ROLE_ADMINISTRATION))
            {
                IsAlowed = false;
            }
        }

        public ActionResult Index()
        {
            return View();
        }

        #region Pages

        public ActionResult Pages()
        {
            return View();
        }

        public string GetPageGroups()
        {
            var pageGroups = _pageManager.GetSitePageGroupsWithPagesAndContentBlocks();

            var result = String.Empty;

            try
            {
                result = JsonConvert.SerializeObject(pageGroups, Formatting.None, new JsonSerializerSettings()
                {
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                    PreserveReferencesHandling = PreserveReferencesHandling.None,
                    //prevent circular reference when model too complicated for
                    //PreserveReferencesHandling = PreserveReferencesHandling.Objects
                    //ContractResolver = new ShouldSerializeContractResolver()
                });
            }
            catch(Exception e)
            {
                _logger.LogError(e);
            }

            return result;
        }

        public string GetLanguages()
        {
            string[] Languages = _pageManager.GetCultures().Select(x => x.Name).ToArray();

            var result = JsonConvert.SerializeObject(Languages, Formatting.Indented, new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                PreserveReferencesHandling = PreserveReferencesHandling.None
            });

            return result;
        }

        public string GetContentBlockDefinitions()
        {
            var contentBlockDefinitions = _pageManager.GetContentBlockDefinitions();

            var result = JsonConvert.SerializeObject(contentBlockDefinitions, Formatting.Indented, new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                //prevent circular reference
                PreserveReferencesHandling = PreserveReferencesHandling.None
            });

            return result;
        }

        [HttpPost]
        public string SetPageGroups(List<SitePageGroup> sitePageGroups)
        {
            return _pageManager.UpdateSitePageGroupsWithPages(sitePageGroups);
        }

        #endregion

        #region Cache

        public ActionResult Cache()
        {
            return View();
        }

        public string GetCacheTable()
        {
            var cacheTable = _cacheManager.GetCacheTable();

            var result = JsonConvert.SerializeObject(cacheTable, Formatting.Indented, new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                PreserveReferencesHandling = PreserveReferencesHandling.None
            });

            return result;
        }

        [HttpPost]
        public string SetCacheTable(List<CacheTable> cacheTableList)
        {
            if (cacheTableList == null)
                throw new ArgumentNullException("CacheTableList is null!");
            return _cacheManager.UpdateCacheTable(cacheTableList);
        }

        public string UpdateCacheTable()
        {
            var cacheTable = _cacheManager.RefreshCacheTable();

            var result = JsonConvert.SerializeObject(cacheTable, Formatting.Indented, new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                PreserveReferencesHandling = PreserveReferencesHandling.None
            });

            return result;
        }

        public string ClearCache()
        {
            return _cacheManager.ClearAllCache();
        }

        #endregion

        #region Users and Roles

        public ActionResult ManageUsers()
        {
            var users = _userManager.GetAllUsers();
            return View(users);
        }

        public ActionResult DeleteUser(string userName)
        {
            _userManager.DeleteUser(userName);
            return RedirectToAction("ManageUsers");
        }

        public ActionResult ManageRoles()
        {
            var roles = _userManager.GetAllRoles();
            return View(roles);
        }

        #endregion

        #region Store

        public ActionResult Store(int? categoryId)
        {
            ViewBag.IsHideHr = "hide";
            ViewBag.InitCategoryId = categoryId ?? 0;

            return View();
        }

        public string GetStoreCategories(int categoryId)
        {
            var categories = _storeManager.GetCategoriesByParentId(UILangName, categoryId);

            var result = JsonConvert.SerializeObject(categories, Formatting.Indented, new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                PreserveReferencesHandling = PreserveReferencesHandling.None
            });

            return result;
        }

        public string GetStoreProducts(int categoryId)
        {
            var products = _storeManager.GetProductsByCategoryId(UILangName, categoryId);

            var result = JsonConvert.SerializeObject(products, Formatting.Indented, new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                PreserveReferencesHandling = PreserveReferencesHandling.None
            });

            return result;
        }

        public string SetCategory(Store_Category_WithProperties storeCategory)
        {
            //write code here
            

            if (storeCategory.IsNewImage)
            {
                var fullImageLink = String.Format("{0}{1}.jpg", ConstantsStore.STR_CATEGORIES_IMAGE_FOLDER, Guid.NewGuid());
                var smallImageLink = String.Format("{0}{1}.jpg", ConstantsStore.STR_CATEGORIES_IMAGE_THUMBS_FOLDER, Guid.NewGuid());

                try
                {
                    FileManager.DownloadFileToServerFolder(new Uri(URLUtils.GetAbsVirtualAppPath() + storeCategory.FullImgLink.Replace("/", "")), fullImageLink, Server);
                    ImageResizer.ResizeImg(Server.MapPath(fullImageLink), Server.MapPath(smallImageLink), 88, 96, 100);
                }
                catch (Exception e)
                {
                    return e.BuildErrorString();
                }
                storeCategory.FullImgLink = fullImageLink;
                storeCategory.SmallImgLink = smallImageLink;
            }
            storeCategory.CultureName = "ru-RU";

            return _storeManager.SaveCategory(storeCategory, UILangName);            

        }

        public ActionResult EditProduct(int id, int? categoryId)
        {

            var product = _storeManager.GetProductById(UILangName, id);

            ViewBag.productId = product.Id;
           
            return View(product);
        }

        public string GetProduct(int productId)
        {
            var product = _storeManager.GetProductById(UILangName, productId);

            var productJson = JsonConvert.SerializeObject(product, Formatting.Indented, new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                PreserveReferencesHandling = PreserveReferencesHandling.None
            });

            return productJson;
        }

        public string AddProduct(int categoryId)
        {
            var id = _storeManager.CreateNewProduct(UILangName, categoryId);

            var product = _storeManager.GetProductById(UILangName, id);
        
             var result = JsonConvert.SerializeObject(product, Formatting.Indented, new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                PreserveReferencesHandling = PreserveReferencesHandling.None
            });

            return result;
        }

        public string SetProduct(Store_Product_WithProperties product)
        {
            _storeManager.SaveProducts(product, UILangName);
            return "OK";
        }

        public string DeleteProduct(int id, int? categoryId)
        {             
            return _storeManager.DeleteProduct(id);
        }

        [HttpPost]
        public ActionResult EditProduct(Store_Product_WithProperties product)
        {
            _storeManager.SaveProducts(product, UILangName);
            return View(_storeManager.GetProductById(UILangName, product.Id));
        }
        //public ActionResult Categories()
        //{
        //    ViewBag.IsHideHr = "hide";


        //    return View();
        //}

        #endregion

        #region Site Administration

        public ActionResult DBAudit()
        {
            return View();
        }

        public string GetDBChangesAudit()
        {
            var dbChangesAudit = _systemSettingsManager.GetDBChangesAudit();

            var result = JsonConvert.SerializeObject(dbChangesAudit, Formatting.Indented, new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                PreserveReferencesHandling = PreserveReferencesHandling.None
            });

            return result;
        }

        public ActionResult SiteMap()
        {
            return View();
        }

        public ActionResult BadLinks()
        {
            return View();
        }

        public string GetBadLinks()
        {
            var badLinks = _systemSettingsManager.GetBadLinks(new Uri(URLUtils.GetAbsVirtualAppPath())).OrderBy(x => x.StatusCode).ThenBy(x => x.FileType);

            var result = JsonConvert.SerializeObject(badLinks, Formatting.Indented, new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                PreserveReferencesHandling = PreserveReferencesHandling.None
            });

            return result;
        }

        #endregion
    }
}
